unit uCompareMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  DBGridEhGrouping, ToolCtrlsEh, DBGridEhToolCtrls, DynVarsEh, DBGridEh,
  Vcl.StdCtrls, Vcl.Mask, DBCtrlsEh, DBLookupEh, EhLibVCL, GridsEh,
  DBAxisGridsEh, Vcl.ComCtrls, System.Win.ComObj, System.UITypes, Vcl.ExtCtrls,
  PrnDbgeh, Vcl.Menus, MemTableEh, MemTableDataEh, Data.DB, DBGridEhImpExp,
  DBSumLst;

type
  TfrmComparer = class(TForm)
    FirstDTP: TDateTimePicker;
    SecondDTP: TDateTimePicker;
    FirstDTPLbl: TLabel;
    SecondDTPLbl: TLabel;
    InvDBGridEh: TDBGridEh;
    PredprDBLCBEh: TDBLookupComboboxEh;
    SearchBtn: TButton;
    LoadExcelFileBtn: TButton;
    XLSOpenDialog: TOpenDialog;
    MainProgressBar: TProgressBar;
    MainStatusBar: TStatusBar;
    UpdateBtn: TButton;
    MainPageControl: TPageControl;
    InvTabSheet: TTabSheet;
    DuplicatesFilialTabSheet: TTabSheet;
    TopPanel: TPanel;
    DuplicatesFilialDBGridEh: TDBGridEh;
    PredprLbl: TLabel;
    SubInvDBGridEh: TDBGridEh;
    PrintDBGridEh: TPrintDBGridEh;
    DuplicatesOblpoTabSheet: TTabSheet;
    DuplicatesOblpoDBGridEh: TDBGridEh;
    SubDuplicatesOblpoDBGridEh: TDBGridEh;
    InstrumentsPanel: TPanel;
    PrintBtn: TButton;
    ShowFiltersBtn: TButton;
    FiltersPanel: TPanel;
    FilialRG: TRadioGroup;
    FilterBtn: TButton;
    ClearFilterBtn: TButton;
    ExportExcelBtn: TButton;
    XLSSaveDialog: TSaveDialog;
    ExportGB: TGroupBox;
    SaveStateGB: TGroupBox;
    SaveStateBtn: TButton;
    LoadStateBtn: TButton;
    StatePM: TPopupMenu;
    SetHidePMBtn: TMenuItem;
    ShowAllStatePMBtn: TMenuItem;
    ShowNotHideStatePMBtn: TMenuItem;
    SetNotHidePMBtn: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure SearchBtnClick(Sender: TObject);
    procedure LoadExcelFileBtnClick(Sender: TObject);
    procedure UpdateBtnClick(Sender: TObject);
    procedure InvDBGridEhRowDetailPanelShow(Sender: TCustomDBGridEh; var CanShow: Boolean);
    procedure InvDBGridEhCheckRowHaveDetailPanel(Sender: TCustomDBGridEh; var RowHaveDetailPanel: Boolean);
    procedure PrintDBGridEhAfterPrint(Sender: TObject);
    procedure DuplicatesOblpoDBGridEhRowDetailPanelShow(Sender: TCustomDBGridEh; var CanShow: Boolean);
    procedure MainPageControlChange(Sender: TObject);
    procedure InvDBGridEhSortMarkingChanged(Sender: TObject);
    procedure PrintBtnClick(Sender: TObject);
    procedure ShowFiltersBtnClick(Sender: TObject);
    procedure ClearFilterBtnClick(Sender: TObject);
    procedure FilterBtnClick(Sender: TObject);
    procedure ExportExcelBtnClick(Sender: TObject);
    procedure SaveStateBtnClick(Sender: TObject);
    procedure LoadStateBtnClick(Sender: TObject);
    procedure StatePMPopup(Sender: TObject);
    procedure SetHidePMBtnClick(Sender: TObject);
    procedure ShowAllStatePMBtnClick(Sender: TObject);
    procedure ShowNotHideStatePMBtnClick(Sender: TObject);
    procedure SetNotHidePMBtnClick(Sender: TObject);
  private
    { Private declarations }
    procedure MultiSorting(DBGridEh: TDBGridEh);
    procedure PrintGrid(DBGridEh: TDBGridEh; title: string);
    procedure SetFilter(DBGridEh: TDBGridEh; _Filter: string);
    procedure ChangeHide(Value: Boolean);
  public
    { Public declarations }
  end;

var
  frmComparer: TfrmComparer;

implementation

uses
  uCompDM, uSearch, uLoadExcelThread, uCompareDataThread, uSaveComeralState;

{$R *.dfm}

procedure TfrmComparer.MultiSorting(DBGridEh: TDBGridEh);
var
  i: Integer;
  s: WideString;
begin
  //Алгоритм сортировки по нескольким полям
  with DBGridEh.SortMarkedColumns do
  begin
    if Count = 0 then
      Exit;

    s := DBGridEh.Columns[Items[0].Index].FieldName;

    if Items[0].Title.SortMarker = smUpEh then
      s := s + ' ASC'
    else
      s := s + ' DESC';

    for i := 1 to Count - 1 do
    try
      s := s + ', ' + DBGridEh.Columns[Items[i].Index].FieldName;

      if Items[i].Title.SortMarker = smUpEh then
        s := s + ' ASC'
      else
        s := s + ' DESC';
    except
    end;
  end;

  s := StringReplace(s, 'StatusText', '[Status]', [rfReplaceAll]);
  CompDM.CompareMemTableEh.SortByFields(s);
end;

procedure TfrmComparer.PrintGrid(DBGridEh: TDBGridEh; title: string);
begin
  PrintDBGridEh.DBGridEh := DBGridEh;
  PrintDBGridEh.Title.Clear;
  PrintDBGridEh.Title.Text := title;
  PrintDBGridEh.Preview;
end;

procedure TfrmComparer.SetFilter(DBGridEh: TDBGridEh; _Filter: string);
begin
  with DBGridEh.DataSource.DataSet do
  begin
    Filtered := False;
    Filter := _Filter;
    Filtered := True;
  end;
end;

procedure TfrmComparer.ChangeHide(Value: Boolean);

  procedure SetHideState(value: Boolean);
  begin
    with CompDM.TmpComeralInvMemTableEh do
    begin
      Edit;
      FieldByName('hide').AsBoolean := value;
      Post;
    end;
  end;

var
  i: Integer;
begin
  with CompDM.TmpComeralInvMemTableEh do
  begin
    DisableControls;

    if InvDBGridEh.SelectedRows.Count = 0 then
      SetHideState(Value)
    else
    begin
      for i := 0 to InvDBGridEh.SelectedRows.Count - 1 do
      begin
        GotoBookmark(pointer(InvDBGridEh.SelectedRows[i]));
        SetHideState(Value);
      end
    end;

    InvDBGridEh.SelectedRows.Clear;
    EnableControls;
  end;
end;

procedure TfrmComparer.SetHidePMBtnClick(Sender: TObject);
begin
  ChangeHide(True);
end;

procedure TfrmComparer.SetNotHidePMBtnClick(Sender: TObject);
begin
  ChangeHide(False);
end;

procedure TfrmComparer.ClearFilterBtnClick(Sender: TObject);
begin
  FilialRG.ItemIndex := -1;

  if (InvDBGridEh.DataSource.Name = 'TmpComeralInvMemTableEhDS') then
    if ShowNotHideStatePMBtn.Checked then
      SetFilter(InvDBGridEh, 'hide=0')
    else
      InvDBGridEh.DataSource.DataSet.Filtered := False
  else
    InvDBGridEh.DataSource.DataSet.Filtered := False;
  DuplicatesFilialDBGridEh.DataSource.DataSet.Filtered := False;
  DuplicatesOblpoDBGridEh.DataSource.DataSet.Filtered := False;
end;

procedure TfrmComparer.DuplicatesOblpoDBGridEhRowDetailPanelShow(Sender:
  TCustomDBGridEh; var CanShow: Boolean);
begin
  with CompDM do
    SelectSprProv(SelectSprProvQ, SelectSvodDuplesOblpodocnumber.AsString,
      SelectSvodDuplesOblponumdocpart.AsString, SelectSvodDuplesOblponumbuhspr.AsString,
      SelectSvodDuplesOblpoidPredpr.AsString,
      SelectSvodDuplesOblpoinvoicefullname.AsString, SelectSvodDuplesOblpodocdate.AsDateTime,
      SelectSvodDuplesOblpofilial.AsInteger);
end;

procedure TfrmComparer.ExportExcelBtnClick(Sender: TObject);
var
  CurrentGrid: TDBGridEh;
begin
  XlsSaveDialog.FileName := 'Камеральный контроль ' + DateToStr(FirstDTP.Date) +
    ' - ' + DateToStr(SecondDTP.Date);

  if XlsSaveDialog.Execute then
  begin
    case MainPageControl.ActivePageIndex of
      0:
        begin
          CurrentGrid := InvDBGridEh;
          CurrentGrid.Columns[0].Visible := True;
        end;
      1:
        CurrentGrid := DuplicatesFilialDBGridEh;
      2:
        CurrentGrid := DuplicatesOblpoDBGridEh;
    else
      begin
        MessageDlg('Данная вкладка не учавствует в печати.', mtWarning, [mbOK], 0);
        Exit;
      end;
    end;

    if not CurrentGrid.DataSource.DataSet.IsEmpty then
      ExportDBGridEhToXlsx(CurrentGrid, XlsSaveDialog.FileName, [], True);

    if MainPageControl.ActivePageIndex = 0 then
      CurrentGrid.Columns[0].Visible := False;

    MessageDlg('Выгрузка в Excel завершена.', mtInformation, [mbOk], 0);
  end;
end;

procedure TfrmComparer.FilterBtnClick(Sender: TObject);
var
  invFilterStr: string;
begin
  if FilialRG.ItemIndex < 0 then
  begin
    if (InvDBGridEh.DataSource.Name = 'TmpComeralInvMemTableEhDS') then
      if ShowNotHideStatePMBtn.Checked then
        SetFilter(InvDBGridEh, 'hide=0')
      else
        InvDBGridEh.DataSource.DataSet.Filtered := False;

    Exit;
  end;

  if (InvDBGridEh.DataSource.Name = 'TmpComeralInvMemTableEhDS') and (ShowNotHideStatePMBtn.Checked) then
    invFilterStr := '(filial=' + FilialRG.Items[FilialRG.ItemIndex] + ' OR filial is NULL) AND hide=0'
  else
    invFilterStr := 'filial=' + FilialRG.Items[FilialRG.ItemIndex] + ' OR filial is NULL';

  SetFilter(InvDBGridEh, invFilterStr);
  SetFilter(DuplicatesFilialDBGridEh, 'dopUNN=' + FilialRG.Items[FilialRG.ItemIndex]);
  SetFilter(DuplicatesOblpoDBGridEh, 'Filial=' + FilialRG.Items[FilialRG.ItemIndex]);
end;

procedure TfrmComparer.FormCreate(Sender: TObject);
begin
  with CompDM do
  begin
    SelectPlatPredpr.Close;
    SelectPlatPredpr.Open;

    SelectOblDopUnn.Close;
    SelectOblDopUnn.Open;
    SelectOblDopUnn.First;

    while not SelectOblDopUnn.Eof do
    begin
      FilialRG.Items.Add(SelectOblDopUnn.FieldByName('dopUnn').AsString);

      SelectOblDopUnn.Next;
    end;
  end;

  FirstDTP.DateTime := Now();
  SecondDTP.DateTime := FirstDTP.DateTime;

  MainPageControl.ActivePageIndex := 0;
end;

procedure TfrmComparer.SaveStateBtnClick(Sender: TObject);
begin
  with CompDM do
  begin
    if not CompareMemTableEh.Active then
    begin
      MessageDlg('Данные для сохранения не найдены.', mtWarning, [mbOK], 0);
      Exit;
    end;

    SaveComeralState := TSaveComeralState.Create(True, MainProgressBar,
      MainStatusBar, MainPageControl, LoadExcelFileBtn, UpdateBtn, InstrumentsPanel);
    SaveComeralState.FreeOnTerminate := true;
    SaveComeralState.Priority := tpNormal;
    SaveComeralState.Start;

//    Screen.Cursor := crSQLWait;
//    ChangeControlEnabled(False);
//
//    try
//      // Удаление старой информации из таблицы
//      DelTmpComeralInvQ.ExecSQL;
//    except
//      on E: Exception do
//      begin
//        MessageDlg('Ошибка удаление информации из таблицы tmpComeralInv, с текстом: '
//          + e.Message, mtError, [mbOK], 0);
//        Screen.Cursor := crDefault;
//        ChangeControlEnabled(True);
//        Exit;
//      end;
//    end;
//
//    // Сохранение текущей сверки в таблицу tmpComeralInv
//    CompareMemTableEh.DisableControls;
//    CompareMemTableEh.First;
//
//    while not CompareMemTableEh.Eof do
//    begin
//      MainProgressBar.Position := CompareMemTableEh.RecNo * 100 div CompareMemTableEh.RecordCount;
//
//      try
//        InsertTmpComeralInv(CompareMemTableEhidPredpr.AsVariant,
//          CompareMemTableEhinvoicefullname.AsVariant, CompareMemTableEhdatetrans.AsVariant,
//          CompareMemTableEhstatus.AsVariant, CompareMemTableEhrecipientname.AsVariant,
//          CompareMemTableEhsignerfio.AsVariant, CompareMemTableEhnamepredpr.AsVariant,
//          CompareMemTableEhdocnumber.AsVariant, CompareMemTableEhdocdate.AsVariant,
//          CompareMemTableEhndsexcel.AsVariant, CompareMemTableEhndsspr.AsVariant,
//          CompareMemTableEhndsinvoice.AsVariant, CompareMemTableEhtotalcostinv.AsVariant,
//          CompareMemTableEhtotalcostvatinv.AsVariant, CompareMemTableEhfilial.AsVariant,
//          CompareMemTableEhsvplace.AsVariant, CompareMemTableEhnumbuhspr.AsVariant,
//          CompareMemTableEhnumdocpart.AsVariant);
//      except
//        on e: EInsTmpComeralInvException do
//          MessageDlg('Произошла ошибка с текстом: ' + e.Message, mtError, [mbOK], 0);
//      end;
//
//      CompareMemTableEh.Next;
//    end;
//
//    CompareMemTableEh.EnableControls;
//
//    MainProgressBar.Style := pbstMarquee;
//    // Сохранение текущих проводок в таблицу tmpComeralProv
//    try
//      RewriteInsTmpComeralProv.ExecSQL;
//    except
//      on e: Exception do
//        MessageDlg('Ошибка перезаписи проводок с текстом: ' + e.Message, mtError, [mbOK], 0);
//    end;
//
//    MainProgressBar.Style := pbstNormal;
//    ChangeControlEnabled(True);
//    Screen.Cursor := crDefault;
//
//    MessageDlg('Сохранение завершено', mtInformation, [mbOK], 0);
  end;
end;

procedure TfrmComparer.SearchBtnClick(Sender: TObject);
begin
  frmSearch := TfrmSearch.Create(Self, PredprDBLCBEh);
  frmSearch.ShowModal;
  frmSearch.Free;
end;

procedure TfrmComparer.ShowAllStatePMBtnClick(Sender: TObject);
begin
  FilterBtn.Click;
end;

procedure TfrmComparer.ShowFiltersBtnClick(Sender: TObject);
begin
  if FiltersPanel.Visible then
  begin
    ShowFiltersBtn.Caption := 'Показать фильтры';
    ShowFiltersBtn.ImageIndex := 5;
    FiltersPanel.Visible := False;
  end
  else
  begin
    ShowFiltersBtn.Caption := 'Скрыть фильтры';
    ShowFiltersBtn.ImageIndex := 4;
    FiltersPanel.Visible := True;
  end;
end;

procedure TfrmComparer.ShowNotHideStatePMBtnClick(Sender: TObject);
begin
  FilterBtn.Click;
end;

procedure TfrmComparer.StatePMPopup(Sender: TObject);
begin
  if InvDBGridEh.DataSource.Name = 'CompareMemTableEhDS' then
    Abort;
end;

procedure TfrmComparer.UpdateBtnClick(Sender: TObject);
var
  idPredpr: Int64;
begin
  // Запуск процесса сверки информации из БД с камеральным контролем
  if FirstDTP.Date > SecondDTP.Date then
  begin
    MessageDlg('Диапазон дат выбран неверно.', mtError, [mbOK], 0);
    Exit;
  end;

  if Length(PredprDBLCBEh.Text) > 0 then
    idPredpr := StrToInt64(VarToStr(PredprDBLCBEh.KeyValue))
  else
    idPredpr := 0;

  with InvDBGridEh do
  begin
    DataGrouping.Active := False;
    DataSource := CompDM.CompareMemTableEhDS;
    DataGrouping.Active := True;
    Columns[16].Visible := False;
  end;

  SubInvDBGridEh.DataSource := CompDM.SelectSprProvDS;

  CompareData := TCompareData.Create(True, idPredpr, FirstDTP.Date, SecondDTP.Date,
    MainProgressBar, MainStatusBar, MainPageControl, LoadExcelFileBtn, UpdateBtn, InstrumentsPanel);
  CompareData.FreeOnTerminate := true;
  CompareData.Priority := tpNormal;
  CompareData.Start;
end;

procedure TfrmComparer.InvDBGridEhCheckRowHaveDetailPanel(Sender:
  TCustomDBGridEh; var RowHaveDetailPanel: Boolean);
begin
  // Отображение детализации только для записей у которых есть сумма по проводкам
  if Sender.DataSource.Name = 'CompareMemTableEhDS' then
    RowHaveDetailPanel := not CompDM.CompareMemTableEhndsspr.IsNull
  else
    RowHaveDetailPanel := not CompDM.TmpComeralInvMemTableEhndsspr.IsNull;
end;

procedure TfrmComparer.InvDBGridEhRowDetailPanelShow(Sender: TCustomDBGridEh; var CanShow: Boolean);
begin
  with CompDM do
    if Sender.DataSource.Name = 'CompareMemTableEhDS' then
      SelectSprProv(SelectSprProvQ, CompareMemTableEhdocnumber.AsString,
        CompareMemTableEhnumdocpart.AsString, CompareMemTableEhnumbuhspr.AsString,
        CompareMemTableEhidPredpr.AsString, CompareMemTableEhinvoicefullname.AsString,
        CompareMemTableEhdocdate.AsDateTime, CompareMemTableEhfilial.AsInteger)
    else
      SelectSprProv(SelectTmpComeralProv, TmpComeralInvMemTableEhdocnumber.AsString,
        TmpComeralInvMemTableEhnumdocpart.AsString,
        TmpComeralInvMemTableEhnumbuhspr.AsString, TmpComeralInvMemTableEhidPredpr.AsString,
        TmpComeralInvMemTableEhinvoicefullname.AsString,
        TmpComeralInvMemTableEhdocdate.AsDateTime, TmpComeralInvMemTableEhfilial.AsInteger);
end;

procedure TfrmComparer.InvDBGridEhSortMarkingChanged(Sender: TObject);
//var number: string;
begin
  with CompDM do
  begin
    if CompareMemTableEh.IsEmpty then
      Exit;

//    number := SelectInvoicesMemNSF.AsString;
    MultiSorting(TDBGridEh(Sender));
//    CompareMemTableEh.Locate('NSF', number, []);
  end;
end;

procedure TfrmComparer.LoadExcelFileBtnClick(Sender: TObject);
begin
  // Запуск процесса считывания XLSX файла во временную таблицу
  if Length(XLSOpenDialog.FileName) > 0 then
    if MessageBox(Self.Handle, PChar('Файл камерального контроля уже был ' +
      'загружен в программу.' + #10#13 + 'Продолжить?'), PChar('Загрузка файла'),
      MB_YESNO + MB_ICONWARNING) = mrNo then
      Exit;

  if not XLSOpenDialog.Execute then
    Exit;

  LoadExcelProcess := TLoadExcelProcess.Create(True, XLSOpenDialog.Files,
    MainProgressBar, MainStatusBar, MainPageControl, LoadExcelFileBtn, UpdateBtn, InstrumentsPanel);
  LoadExcelProcess.FreeOnTerminate := true;
  LoadExcelProcess.Priority := tpNormal;
  LoadExcelProcess.Start;
end;

procedure TfrmComparer.LoadStateBtnClick(Sender: TObject);
begin
  with CompDM do
  begin
    with SelectTmpComeralInv do
    begin
      Close;
      if Length(PredprDBLCBEh.Text) > 0 then
        SQL[2] := 'WHERE ISNULL(idPredpr,0)=' + VarToStr(PredprDBLCBEh.KeyValue)
      else
        SQL[2] := '-- Условие для предприятия';

      Open;

      if IsEmpty then
      begin
        MessageDlg('Сохранённые данные не найдены.', mtWarning, [mbOK], 0);
        Exit;
      end;
    end;

    with InvDBGridEh do
    begin
      DataGrouping.Active := False;
      DataSource := TmpComeralInvMemTableEhDS;
      DataGrouping.Active := True;
      Columns[16].Visible := True;
    end;

    SubInvDBGridEh.DataSource := SelectTmpComeralProvDS;

    TmpComeralInvMemTableEh.Active := False;
    TmpComeralInvMemTableEh.Active := True;
    TmpComeralInvMemTableEh.SortByFields('namepredpr,invoicefullname');
    TmpComeralInvMemTableEh.First;
  end;
end;

procedure TfrmComparer.MainPageControlChange(Sender: TObject);
begin
  // Закрытие панелий детализации при переключении между вкладками
  if InvDBGridEh.RowDetailPanel.Visible then
    InvDBGridEh.RowDetailPanel.Visible := False;

  if DuplicatesOblpoDBGridEh.RowDetailPanel.Visible then
    DuplicatesOblpoDBGridEh.RowDetailPanel.Visible := False;
end;

procedure TfrmComparer.PrintBtnClick(Sender: TObject);
var
  period: string;
begin
  // Печать информации из гридов
  period := 'за период с ' + DateToStr(FirstDTP.Date) + ' по ' + DateToStr(SecondDTP.Date);

  case MainPageControl.ActivePageIndex of
    0:
      begin
        InvDBGridEh.DataGrouping.GroupLevels[0].ExpandNodes;
        PrintGrid(InvDBGridEh, 'Сверка камерального контроля ' + period);
      end;
    1:
      begin
        PrintGrid(DuplicatesFilialDBGridEh, 'Дубликаты проводок в филиалах ' + period);
      end;
    2:
      begin
        PrintGrid(DuplicatesOblpoDBGridEh, 'Дубликаты проводок в облпо ' + period);
      end;
  end;
end;

procedure TfrmComparer.PrintDBGridEhAfterPrint(Sender: TObject);
begin
  // Сворачивание записей после печати
  if MainPageControl.ActivePageIndex = 0 then
    InvDBGridEh.DataGrouping.GroupLevels[0].CollapseNodes;
end;

end.

